/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "ui渲染合成节点菜单.h"
#include "节点类型构建/构建渲染器节点.h"
#include "节点类型构建/构建视频图像节点.h"
#include "渲染/渲染.h"


static S_UI创建环境* g当前UI环境 = nullptr;
static fp_节点创建视口回调 fun_节点视口回调 = 0;
//static std::map<std::string, f_节点面板构建_回调函数指针> g节点面板构建函数;
//static std::map<std::string, f_节点面板重置_回调函数指针> g节点面板重置函数;



static bool f_运行渲染节点树(int32 s, int32 e) {
	for (int32 i = s; i < e; ++i) {
		for (auto& e : S_节点数据::g_根节点树) {
			if (f_NT_StepUpdate节点(e, true) == false) {
				return false;
			}
		}
	}
	return true;
}

static E_事件是否传递 on_渲染单帧(C_Widget* self, uint8 状态) {
	f_render_加入光追渲染任务线程(E_离线渲染状态::e_光追渲染_单帧);
	//S_节点数据::g_开启节点帧更新 = true;
	return E_事件是否传递::e_事件传递_终止;
}

static E_事件是否传递 on_渲染序列(C_Widget* self, uint8 状态) {
	auto& frame = f_NodeCtx_get帧();
	S_节点数据::g_渲染帧编号 = f_prop_iVec2(frame.帧区间).x;
	//S_节点数据::g_开启节点帧更新 = true;
	f_render_加入光追渲染任务线程(E_离线渲染状态::e_光追渲染_序列);
	return E_事件是否传递::e_事件传递_终止;
}

static E_事件是否传递 on_节点离线更新(C_Widget* self, uint8 状态) {
	auto& frame = f_NodeCtx_get帧();
	S_节点数据::g_渲染帧编号 = f_prop_iVec2(frame.帧区间).x;
	//S_节点数据::g_开启节点帧更新 = true;
	f_render_加入光追渲染任务线程(E_离线渲染状态::e_离线计算_序列);
	return E_事件是否传递::e_事件传递_终止;
}


E_事件是否传递 f_工作区_停止渲染计算(C_Widget* self, uint8 状态) {
	S_光追后端::g_渲染状态 = E_离线渲染状态::e_光追渲染_关;
	f_render_等待渲染停止();
	std::cout<<"停止渲染"<< std::endl;
	return E_事件是否传递::e_事件传递_终止;
}




void f_init_渲染合成节点创建_绑定视口回调(fp_节点创建视口回调 fun) {
	fun_节点视口回调 = fun;

	C_节点面板::g节点面板构建函数[DEF_渲染器配置节点] = f_节点构建_渲染器配置;
	C_节点面板::g节点面板重置函数[DEF_渲染器配置节点] = f_节点重置_渲染器配置;

	C_节点面板::g节点面板构建函数[DEF_渲染输出节点] = f_节点构建_渲染输出;
	C_节点面板::g节点面板重置函数[DEF_渲染输出节点] = f_节点重置_渲染输出;



	S_键盘键位映射 快捷键 = {};
	for (uint8 i = 0; i < 4; ++i) {
		快捷键.键盘按键[i] = 0;
		快捷键.键盘状态[i] = 0;
	}
	快捷键.键盘按键[0] = S_InputKey::e_KEY_右CTRL;
	快捷键.键盘状态[0] = DEF_按键状态_按下中 | DEF_按键状态_按下;
	快捷键.键盘按键[1] = S_InputKey::e_KEY_F11;
	快捷键.键盘状态[1] = DEF_按键状态_按下;
	快捷键.event = on_渲染序列;
	f_ui_注册全局快捷键(快捷键);


	for (uint8 i = 0; i < 4; ++i) {
		快捷键.键盘按键[i] = 0;
		快捷键.键盘状态[i] = 0;
	}
	快捷键.键盘按键[0] = S_InputKey::e_KEY_F11;
	快捷键.键盘状态[0] = DEF_按键状态_按下中;
	快捷键.event = on_渲染单帧;
	f_ui_注册全局快捷键(快捷键);

	

	快捷键 = {};
	快捷键.event = f_工作区_停止渲染计算;
	快捷键.键盘按键[0] = S_InputKey::e_ESC;
	快捷键.键盘状态[0] = DEF_按键状态_放开;
	f_ui_注册全局快捷键(快捷键);


}






static void on_2级节点_颜色节点创建菜单项(C_Widget* self, const std::wstring name, uint16 id) {

}

static void on_1级节点_渲染合成节点创建菜单项(C_Widget* self, const std::wstring name, uint16 id) {
	C_节点面板* node = nullptr;
	if (name == L"渲染器配置") {
		node = f_节点构建_渲染器配置(*g当前UI环境, *S_框架::g_3D视口环境, nullptr);
	}
	else if (name == L"渲染输出") {
		node = f_节点构建_渲染输出(*g当前UI环境, *S_框架::g_3D视口环境, nullptr);
	}
	else if (name == L"着色器") {
		node = f_节点构建_着色器(*g当前UI环境, *S_框架::g_3D视口环境, nullptr);
	}
	else if (name == L"材质") {
		node = f_节点构建_材质(*g当前UI环境, *S_框架::g_3D视口环境, nullptr);
	}
	if (node) fun_节点视口回调(node, true);
}



C_Widget* f_init渲染合成节点创建菜单(S_UI创建环境& ctx) {
	g当前UI环境 = &ctx;


	S_菜单创建参数 颜色项创建参数 = {
		on_2级节点_颜色节点创建菜单项, {

			{L"混合", "", 0},
			{L"分离RGB", "几何", 0},
		}
	};


	S_菜单创建参数 菜单创建参数 = {
		on_1级节点_渲染合成节点创建菜单项, {
			{L"渲染器配置", "相机", nullptr},
			{L"渲染输出", "相机", nullptr},
		    {L"颜色", "颜色滤镜", &颜色项创建参数},
		    {L"材质", "", nullptr},

		}
	};


	auto* menu = f_ui_创建菜单(e_纵向, 菜单创建参数, ctx);

	return menu;
}

C_节点面板* f_渲染合成节点构建_从节点构建节点(C_节点基类* node, bool 是否关联, bool 创建新节点) {
	C_节点面板* newNode = nullptr;
	if (创建新节点) {
		newNode = C_节点面板::g节点面板构建函数[node->m_TypeName](*g当前UI环境, *S_框架::g_3D视口环境, nullptr, nullptr);
	}
	else {
		newNode = C_节点面板::g节点面板构建函数[node->m_TypeName](*g当前UI环境, *S_框架::g_3D视口环境, node, nullptr);
	}
	
	return newNode;
}

C_节点面板* f_渲染合成节点构建_重构(C_节点面板* plane, C_节点基类* node) {
	if (!plane) {
		auto it = C_节点面板::g节点面板构建函数.find(node->m_TypeName);
		if (it != C_节点面板::g节点面板构建函数.end()) {
			plane = (it->second)(*g当前UI环境, *S_框架::g_3D视口环境, node, nullptr);
		}
	}
	else {
		auto it = C_节点面板::g节点面板重置函数.find(node->m_TypeName);
		if (it != C_节点面板::g节点面板重置函数.end()) {
			(it->second)(plane, node);
		}
	}
	assert(plane);
	return plane;
}





void on_重载渲染器菜单项(C_Widget* self, const std::wstring name, uint16 id) {
	if (name == L"渲染单帧") {
		on_渲染单帧(nullptr, 0);
	}
	else if (name == L"渲染序列") {
		on_渲染序列(nullptr, 0);
	}
	else if (name == L"渲染重载") {
		auto* scene = f_NodeCtx_get默认场景();
		scene->m_光追后端->f_重载();
	}
	else if (name == L"节点离线更新") {
		on_节点离线更新(nullptr, 0);
	}
}




